;(function($){

$.fn.ajaxLoader = function() {
	var loader = "<div id='ajax_loader' style='margin:10px;'><img src='resource/img/ajax-loader.gif' /></div>";
	$(this).html(loader);
};
	
/**
 * options = {
 * 	url : #url, //the url which it will be post
 * 	params : {} //parameters
 * 	success : function, //the function to callback after post
 * 	loader : true,	//whether to show loader.gif	
 * }
 */
$.fn.ajaxPostOptions = function(options) {
	if (!this.length) {
		log('no element selected');
		return this;
	}
	
	if (typeof options == 'function') {
		options = { success: options };
	}	

	// clean url (don't include hash vaue)
	if(options.url) {
		options.url = (options.url.match(/^([^#]+)/)||[])[1];
	}
	options.url = options.url || window.location.href || '';
	
	options = $.extend(true, {
		params : {},
		success : $.ajaxSettings.success,
		loading : true
	}, options);
	
	$(this).ajaxLoader();
	$.post(options.url, function(data) {
		options.loader.html(data);
		if(options.success) {
			options.success();
		} 
	});
	
};


$.fn.ajaxPost = function(url, func) {
	this.ajaxPostOptions({
		url : url,
		success : func,
		loader : this
	}); 
};
	
})(jQuery);

var ajax = {

	postHtml : function(id, url, callback, options) {
		ajax.ajax_loader(id);
		$.post(url, function(data) {
			$("#" + id).html(data);
			if(callback){				
				callback();	
			}
		});
	}
};

/**
 * @description 表格控制
 * 
 * @example $('table').nfTable();
 * @desc 简单表格控制
 * 
 */
$.fn.nfTable = function( settings ) {
    this.defaults = {
        cssHeader: "header",
        cssAsc: "sorting_asc",
        cssDesc: "sorting_desc",
        cssChildRow: "expand-child",
        sortInitialOrder: "asc",
        sortMultiSortKey: "shiftKey",
        sortForce: null,
        sortAppend: null,
        sortLocaleCompare: true,
        textExtraction: "simple",
        parsers: {}, widgets: [],
        widgetZebra: {
            css: ["even", "odd"]
        }, headers: {}, widthFixed: false,
        cancelSelection: true,
        sortList: [],
        headerList: [],
        dateFormat: "us",
        decimal: '/\.|\,/g',
        onRenderHeader: null,
        selectorHeaders: 'thead th',
        debug: false,
        
        
        ajaxSource : ajaxUrl
        
        
    };
    
    
    function setHeadersCss(table, $headers, list, css) {
        // remove all header information
        $headers.removeClass(css[0]).removeClass(css[1]);

        var h = [];
        $headers.each(function (offset) {
            if (!this.sortDisabled) {
                h[this.column] = $(this);
            }
        });

        var l = list.length;
        for (var i = 0; i < l; i++) {
            h[list[i][0]].addClass(css[list[i][1]]);
        }
    }
    
    
    function checkHeaderOptions(table, i) {
        if ((table.config.headers[i]) && (table.config.headers[i].sorter === false)) {
            return true;
        };
        return false;
    }
    
    
    function computeTableHeaderCellIndexes(t) {
        var matrix = [];
        var lookup = {};
        var thead = t.getElementsByTagName('THEAD')[0];
        var trs = thead.getElementsByTagName('TR');

        for (var i = 0; i < trs.length; i++) {
            var cells = trs[i].cells;
            for (var j = 0; j < cells.length; j++) {
                var c = cells[j];

                var rowIndex = c.parentNode.rowIndex;
                var cellId = rowIndex + "-" + c.cellIndex;
                var rowSpan = c.rowSpan || 1;
                var colSpan = c.colSpan || 1;
                var firstAvailCol;
                if (typeof(matrix[rowIndex]) == "undefined") {
                    matrix[rowIndex] = [];
                }
                // Find first available column in the first row
                for (var k = 0; k < matrix[rowIndex].length + 1; k++) {
                    if (typeof(matrix[rowIndex][k]) == "undefined") {
                        firstAvailCol = k;
                        break;
                    }
                }
                lookup[cellId] = firstAvailCol;
                for (var k = rowIndex; k < rowIndex + rowSpan; k++) {
                    if (typeof(matrix[k]) == "undefined") {
                        matrix[k] = [];
                    }
                    var matrixrow = matrix[k];
                    for (var l = firstAvailCol; l < firstAvailCol + colSpan; l++) {
                        matrixrow[l] = "x";
                    }
                }
            }
        }
        return lookup;
    }
    
    
    function buildHeaders(table) {
        var header_index = computeTableHeaderCellIndexes(table);

        $tableHeaders = $(table.config.selectorHeaders, table).each(function (index) {

            this.column = header_index[this.parentNode.rowIndex + "-" + this.cellIndex];
            // this.column = index;
            this.order = formatSortingOrder(table.config.sortInitialOrder);
            
			
			this.count = this.order;

            if (checkHeaderMetadata(this) || checkHeaderOptions(table, index)) this.sortDisabled = true;
			if (checkHeaderOptionsSortingLocked(table, index)) this.order = this.lockedOrder = checkHeaderOptionsSortingLocked(table, index);

            if (!this.sortDisabled) {
                var $th = $(this).addClass(table.config.cssHeader);
                if (table.config.onRenderHeader) table.config.onRenderHeader.apply($th);
            }

            // add cell to headerList
            table.config.headerList[index] = this;
        });

        if (table.config.debug) {
            benchmark("Built headers:", time);
            log($tableHeaders);
        }

        return $tableHeaders;

    };    
    
    var $this, $document, $headers, cache, config, shiftDown = 0, sortOrder;
    // if no thead or tbody quit.
    if (!this.tHead || !this.tBodies) return;
    this.config = {};
    // merge and extend.
    config = $.extend(this.config, $.nfTable.defaults, settings);
    $this = $(this);
    // save the settings where they read
    $.data(this, "nfTable", config);
    
    // get the css class names, could be done else where.
    var sortCSS = [config.cssDesc, config.cssAsc];
    // build headers
    $headers = buildHeaders(this);
    $headers.click(function(e){
        if (!this.sortDisabled && totalRows > 0) {
            // store exp, for speed
            var $cell = $(this);
            // get current column index
            var i = this.column;
            // get current column sort order
            this.order = this.count++ % 2;
            // the user has clicked on an all
            // ready sortet column.
            if (isValueInArray(i, config.sortList)) {
                // revers the sorting direction
                // for all tables.
                for (var j = 0; j < config.sortList.length; j++) {
                    var s = config.sortList[j],
                        o = config.headerList[s[0]];
                    if (s[0] == i) {
                        o.count = s[1];
                        o.count++;
                        s[1] = o.count % 2;
                    }
                }
            } else {
                // add column to sort list array
                config.sortList.push([i, this.order]);
            }
            
            // set css for headers
            setHeadersCss($this[0], $headers, config.sortList, sortCSS);
        }
    });
}; 


